package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSONObject;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.AmountUtil;
import com.huiminpay.common.cache.util.EncryptUtil;
import com.huiminpay.common.cache.util.PaymentUtil;
import com.huiminpay.merchant.api.AppService;
import com.huiminpay.merchant.api.MerchantService;
import com.huiminpay.paymentagent.api.PayChannelAgentService;
import com.huiminpay.paymentagent.api.conf.AliConfigParam;
import com.huiminpay.paymentagent.api.dto.AlipayBean;
import com.huiminpay.paymentagent.api.dto.PaymentResponseDTO;
import com.huiminpay.transaction.api.PayChannelService;
import com.huiminpay.transaction.api.TransactionService;
import com.huiminpay.transaction.api.dto.PayChannelParamDTO;
import com.huiminpay.transaction.api.dto.PayOrderDTO;
import com.huiminpay.transaction.api.dto.QRCodeDto;
import com.huiminpay.transaction.convert.PayOrderConvert;
import com.huiminpay.transaction.entity.PayOrder;
import com.huiminpay.transaction.mapper.PayOrderMapper;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.time.LocalDateTime;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 有点儿意思
 * @Description:
 */
@Service
public class TransactionServiceImpl implements TransactionService {

    @Value("${huiminpay.payurl}")
    private String payurl;

    @Reference
    AppService appService;

    @Reference
    MerchantService merchantService;

    @Autowired
    PayOrderMapper payOrderMapper;

    @Reference
    PayChannelAgentService payChannelAgentService;

    @Reference
    PayChannelService payChannelService;

    /**
     * 生成二維碼地址封裝參數
     *
     * @param qrCodeDto 商戶id 應用id  门店id 支付标题  描述
     * @return 二维码地址
     * @throws BusinessException
     */
    @Override
    public String createStoreQrcode(QRCodeDto qrCodeDto) throws BusinessException {
        //非空参数判断
        if (qrCodeDto == null){
            throw new BusinessException(CommonErrorCode.E_200007);
        }
        //校验应用是否属于商户
        //校验门店是否属于商户
        this.queryAppAndStore(qrCodeDto.getMerchantId(), qrCodeDto.getStoreId(), qrCodeDto.getAppId());
        // 形成订单 封装在订单对象中
        PayOrderDTO payOrderDTO = new PayOrderDTO();
        BeanUtils.copyProperties(qrCodeDto, payOrderDTO);
        //设置服务类型
        payOrderDTO.setChannel("huimin_c2b");
        //处理参数
        String jsonString = JSONObject.toJSONString(payOrderDTO);
        //编码处理
        String ticket = EncryptUtil.encodeUTF8StringBase64(jsonString);
        // 格式：http://localhost:56050/transaction/pay-entry/sdfasfasfdaf5y34y5sdfsdfa(ticket)
        return payurl+ticket;
    }

    /**
     * 保存订单 & 调代理服务对接支付宝下单接口
     * @param payOrderDTO 订单对象
     * @return 接口地址
     * @throws BusinessException
     */
    @Override
    public PaymentResponseDTO<String> submitOrderByAli(PayOrderDTO payOrderDTO) throws BusinessException {
        //设置支付渠道
        payOrderDTO.setPayChannel("ALIPAY_WAP");
        //保存订单信息
        PayOrderDTO orderDTO = this.saveOrder(payOrderDTO);
        //调代理服务对接支付宝接口
        return this.alipayH5(orderDTO);
    }


    /**
     * 调代理服务中阿里支付宝接口的方法
     * @return 支付宝调用服务地址
     */
    private PaymentResponseDTO<String> alipayH5(PayOrderDTO orderDTO){
        //组装参数
        //1、公共请求参数（支付渠道参数的东西）

        PayChannelParamDTO platformChannel = payChannelService.queryPayChannelParamByAppPlatformChannel(orderDTO.getAppId(),
                orderDTO.getChannel(), orderDTO.getPayChannel());
        if (platformChannel == null){
            throw new BusinessException(CommonErrorCode.E_300007);
        }
        //获取支付渠道参数
        String channelParam = platformChannel.getParam();
        //转成对象
        AliConfigParam aliConfigParam = JSONObject.parseObject(channelParam, AliConfigParam.class);
        aliConfigParam.setCharest("utf-8");
        //2、业务请求参数
        AlipayBean alipayBean = new AlipayBean();
        alipayBean.setOutTradeNo(orderDTO.getTradeNo());
        alipayBean.setSubject(orderDTO.getSubject());
        //处理 元转分
        // 分转元
        Integer totalAmount = orderDTO.getTotalAmount();
        try {
            alipayBean.setTotalAmount(AmountUtil.changeF2Y(String.valueOf(totalAmount)));
        } catch (Exception e) {
            throw new BusinessException(CommonErrorCode.E_300006);
        }
        alipayBean.setProductCode("QUICK_WAP_WAY");
        alipayBean.setBody(orderDTO.getBody());
        alipayBean.setExpireTime("30m");
        alipayBean.setStoreId(orderDTO.getStoreId());
        return payChannelAgentService.createPayOrderByAliWap(aliConfigParam, alipayBean);
    }
    /**
     * 保存订单信息
     * @param payOrderDTO  订单信息
     * @return 订单对象
     */
    private PayOrderDTO saveOrder(PayOrderDTO payOrderDTO){

        PayOrder payOrder = PayOrderConvert.INSTANCE.dto2entity(payOrderDTO);
        //设置订单号
        payOrder.setTradeNo(PaymentUtil.genUniquePayOrderNo());
        //设置币种
        payOrder.setCurrency("CNY");
        //总金额  元转分
        String totalAmount = AmountUtil.changeY2F(Long.valueOf(payOrderDTO.getTotalAmount()));
        payOrder.setTotalAmount(Integer.parseInt(totalAmount));
        //订单状态
        payOrder.setTradeState("0");
        //创建时间
        payOrder.setCreateTime(LocalDateTime.now());
        //设置过期时间
        payOrder.setExpireTime(LocalDateTime.now().plusMinutes(30));
        payOrderMapper.insert(payOrder);
        return PayOrderConvert.INSTANCE.entity2dto(payOrder);
    }

    /**
     * 校验门店和应用是否属于商户
     * @param merchantId 商户id
     * @param storeId 门店id
     * @param appId 应用id
     */
    private void queryAppAndStore(Long merchantId,Long storeId,String appId){
        if (!appService.queryAppInMerchant(appId,merchantId)) {
            throw new BusinessException(CommonErrorCode.E_200005);
        }
        if (!merchantService.queryStoreInMerchant(storeId, merchantId)){
            throw new BusinessException(CommonErrorCode.E_200006);
        }
    }
}
